<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="https://cdn.staticfile.org/vue/2.6.11/vue.min.js"></script>
</head>

<body>
  <div id="app">
    <div v-if="isShow">
      <p>昵称：<input type="text" v-model="name"></p>
      <p>uid：<input type="text" v-model="uid"></p>
      <p>房间号：<input type="text" v-model="roomid"></p>
      <button type="button" @click="enter()">进入聊天室</button>
    </div>
    <div v-else>
      <ul>
        <li v-for="(item,index) in lists" :key="'message' + index">{{item}}</li>
        <li>在线人数{{num}}</li>
      </ul>
      <div class="ctrl">
        <input type="text" v-model="message">
        <button type="button" @click="send()">按钮</button>
      </div>
    </div>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: '',
        lists: [],
        ws: {},
        name: '',
        isShow: true,
        num: 0,
        roomid: '',
        uid: '',
        handle: {}
      },
      mounted() {
      },
      methods: {
        init() {
          this.ws = new WebSocket('ws://127.0.0.1:3000')
          this.ws.onopen = this.onOpen
          this.ws.onmessage = this.onMessage
          this.ws.onclose = this.onClose
          this.ws.onerror = this.onError
        },
        enter() {
          if (this.name.trim() === '') {
            alert('用户名不得为空')
            return
          }
          this.init()
          this.isShow = false
        },
        onOpen: function () {
          // console.log('open:' + this.ws.readyState);
          //ws.send('Hello fro,m client!')
          // 发起鉴权请求
          //this.ws.send(JSON.stringify({
          //  event: 'auth',
          //  message: //'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIx//MjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNT//E2MjM5MDIyfQ.//XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o'
          //}))
          this.ws.send(JSON.stringify({
            event: 'enter',
            message: this.name,
            roomid: this.roomid,
            uid: this.uid
          }))
        },
        onMessage: function (event) {
          // 当用户未进入聊天室，则不接收消息
          if (this.isShow) {
            return
          }
          // 接收服务端发送过来的消息
          var obj = JSON.parse(event.data)
          switch (obj.event) {
            case 'noauth':
              // 鉴权失败
              // 路由跳转到 /login 重新获取token
              break;
            case 'enter':
              // 当有一个新的用户进入聊天室
              this.lists.push('欢迎：' + obj.message + '加入聊天室！')
              break;
            case 'out':
              this.lists.push(obj.name + '已经退出了聊天室！')
              break;
            case 'heartbeat':
              //this.checkServer() // timeInterval + t
              // 可以注释掉以下心跳状态，主动测试服务端是否会断开客户端的连接
              this.ws.send(JSON.stringify({
                event: 'heartbeat',
                message: 'pong'
              }))
              break
            default:
              if (obj.name !== this.name) {
                // 接收正常的聊天
                this.lists.push(obj.name + ':' + obj.message)
              }
          }
          this.num = obj.num
        },
        onClose: function () {
          // 当链接主动断开的时候触发close事件
          console.log('close:' + this.ws.readyState);
          console.log('已关闭websocket');
          this.ws.close()
        },
        onError: function () {
          // 当连接失败时，触发error事件
          console.log('error:' + this.ws.readyState);
          console.log('websocket连接失败！');
          // 连接失败之后，1s进行断线重连！
          var _this = this
          setTimeout(function () {
            _this.init()
          }, 1000)
        },
        // 发送消息
        send: function () {
          this.lists.push(this.name + ':' + this.message)
          this.ws.send(JSON.stringify({
            event: 'message',
            message: this.message,
            name: this.name
          }))
          this.message = ''
        },
        checkServer: function () {
          var _this = this
          clearTimeout(this.handle)
          this.handle = setTimeout(function () {
            _this.onClose()
            setTimeout(function () {
              _this.init()
            }, 1000)
            // 设置1ms的时延，调试在服务器测未及时响应时，客户端的反应
          }, 30000 + 1000)
        }
      }
    })
  </script>
</body>

</html>